import subprocess
import sys
import os
import os.path

#codename = os.path.splitext(os.path.basename(sys.argv[0]))[0]
gcctarget = "g++"

def execute(*cmd):
	try:
		#print " ".join(cmd)
		#return 0
		retcode = subprocess.call(" ".join(cmd), shell=True)
		#if retcode < 0:
		#	print "Child was terminated by signal", -retcode
		#else:
		#	print "Child returned", retcode
		return retcode
	except OSError, e:
		print "Execution failed:", e
		return -1
		
def compileLibrary(codename, ext, buildDirectory):
	if buildDirectory[-1] == "\\": buildDirectory = buildDirectory[:-1]
	print "\n\nCreating ", codename.strip() + ".pyd"
	
	print "\n- Creating shared path"
	execute("mkdir", os.path.join(buildDirectory, os.path.dirname(codename)))

	print "\n- Using cython"
	r = execute("cython", codename+ext, "-o", buildDirectory + '\\' +  codename+".c")
	if r < 0: return r
	
	print "\n- Using mingw32 compiler"
	r = execute(
		'mingw32-'+gcctarget+'.exe',
		'-Wall','-fexceptions',
		'-O2',
		'-g',
		r'-I"c:\program files\python27\include"',
		'-c', buildDirectory + '\\' + codename + '.c',
		'-o', buildDirectory + '\\' + codename + '.o'
		)
	if r < 0: return r

	print "\n- Creating shared library"
	r = execute(
		'mingw32-' + gcctarget + '.exe',
		'-shared',
		'-Wl,--dll',
		buildDirectory + '\\' + codename + '.o',
		'-o', buildDirectory + '\\' + codename + '.dll',
		'-s', '"C:\Program Files\Python27\libs\libpython27.a"'
		)
	if r < 0: return r

	print "\n- Creating python shared module"
	return execute(
		'copy',
		buildDirectory + '\\' + codename + '.dll',
	buildDirectory + '\\' + codename + '.pyd')

def compileApplication(codename, ext, buildDirectory):
	if buildDirectory[-1] == "\\": buildDirectory = buildDirectory[:-1]
	print "\n\nCreating ", codename.strip() + ".exe"
	
	print "\n- Creating shared path"
	execute("mkdir", os.path.join(buildDirectory, os.path.dirname(codename)))

	print "\n- Using cython"
	r = execute("cython", codename+ext, "--embed", "-o", buildDirectory + "\\" + codename+".c",)
	if r < 0: return r

	print "\n- Using mingw32 compiler"
	r = execute(
		'mingw32-gcc.exe',
		'-g',
		#'-O2',
		r'-I"c:\program files\python27\include"',
		'-c', buildDirectory + "\\" + codename + '.c',
		'-o', buildDirectory + '\\' + codename + '.o'
		)
	if r < 0: return r

	print "\n- Creating standalone executable"
	r = execute(
		'mingw32-g++.exe',
		'-o', buildDirectory + '\\' + codename + '.exe',
		buildDirectory + '\\' + codename + '.o',
		'"C:\Program Files\Python27\libs\libpython27.a"'
		)
	if r < 0: return r
	
	startdir = "__init__"
	if codename[-len(startdir):] == startdir:
		print "\n- Copying python start directory"
		return execute(
			'copy',
			codename + ".py",
		buildDirectory + '\\' + codename + '.py')
	
def compileCurrentPyFiles(path):
	allow_ext = ['.py', '.pyx', '.pxd']
	print os.path.splitext(os.path.basename(sys.argv[0]))[0], " Cython Compiler Automatisation Tool"
	#files = [os.path.splitext(name) for name in os.listdir(os.path.dirname(os.path.realpath(path))) if os.path.splitext(name)[1] in allow_ext]
	allfiles = []
	first = True
	for root, dirs, files in os.walk(os.path.dirname(os.path.realpath(path))):
		if first:
			lroot = len(root)+1
			first = False
		for file in files:
			filename = os.path.join(root,file)[lroot:]
			dirname = ""#os.path.dirname(filename)
			filenameext = os.path.splitext(filename)
			if filenameext[1] in allow_ext:
				allfiles.append((filenameext[0],filenameext[1],dirname))
				#allfiles.append(os.path.splitext(file))
	#print allfiles
	#print [os.path.splitext(name) for name in os.listdir(os.path.dirname(os.path.realpath(path))) if os.path.splitext(name)[1] in allow_ext]
	#return
	retval = True
	#for file in files:
	separator = "\n" + "=" * 79
	for file, ext, dirname in allfiles:
		#if compileLibrary(codename = file[0], ext = file[1], buildDirectory = '__shared__') < 0:
		if compileLibrary(codename = file, ext = ext, buildDirectory = '__shared__') < 0:
			print "\n- Error creating library"
			retval = False
		print separator
		#if compileApplication(codename = file[0], ext = file[1], buildDirectory = '__bin__') < 0:
		if compileApplication(codename = file, ext = ext, buildDirectory = '__bin__') < 0:
			print "\n- Error creating standalone application"
			retval = False
		print separator
	return retval

try:
	if not compileCurrentPyFiles(sys.argv[0]):
		print "\n Some errors have been happened! Press <enter> to exit"
		raw_input()
except Exception, e:
	print "Execution failed:",e
	raw_input()